package org.summerframework.component.upload.oss;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import org.summerframework.component.upload.AbstractUploadServerService;
import org.summerframework.component.upload.FileUploadServerService;
import org.summerframework.component.upload.UploadResultCode;
import org.summerframework.component.upload.config.UploadConfiguration;
import org.summerframework.core.exception.WebException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

/**
 * @author 石超
 * @version v1.0.0
 */
@Slf4j
public class OSSUploadServerServiceImpl extends AbstractUploadServerService implements FileUploadServerService {
    private String bucketName;
    private OSS ossClient;
    private UploadConfiguration.OSS oss;

    public OSSUploadServerServiceImpl(UploadConfiguration.OSS oss) {
        this.oss = oss;
        this.bucketName = oss.getBucketName();
        this.ossClient = new OSSClientBuilder().build(oss.getEndpoint(), oss.getAccessKeyId(), oss.getSecret());

        if (oss.isAuto()) {
            Bucket bucket = ossClient.createBucket(bucketName);
            log.info("{}", bucket);
        }
    }

    @Override
    public String uploadFile(InputStream is, String fileName) {
        String path = getPath(fileName);

        try {
            ossClient.putObject(bucketName, replacePath(path), is);
        } catch (OSSException | ClientException e) {
            throw new WebException(UploadResultCode.ERROR_UPLOAD_FAILURE, e);
        }

        return path;
    }

    @Override
    public byte[] getFileBytes(String path) {
        try {
            OSSObject ossObject = ossClient.getObject(bucketName, replacePath(path));

            return IOUtils.toByteArray(ossObject.getObjectContent());
        } catch (IOException e) {
            e.printStackTrace();
            return EMPTY_BYTES;
        }
    }

    @Override
    public InputStream getInputStream(String path) throws Exception {
        final GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, replacePath(path));
        getObjectRequest.addParameter("x-oss-process", "image/resize,m_lfit,w_540,h_540");
        OSSObject ossObject = ossClient.getObject(getObjectRequest);
        return ossObject.getObjectContent();
    }

    @Override
    public void deleteFile(String path) {
        try {
            ossClient.deleteObject(bucketName, replacePath(path));
        } catch (OSSException | ClientException e) {
            log.warn("删除失败", e);
        }
    }

    private String replacePath(String path) {
        if (path.startsWith("/")) {
            path = path.substring(1);
        }

        return path;
    }

    @Override
    public String getUrl(String path) {
        if (oss.isOssUrl()) {
            if (oss.isEncrypt()) {
                URL url = ossClient.generatePresignedUrl(oss.getBucketName(), StringUtils.substring(path, 1),
                        new Date(System.currentTimeMillis() + oss.getExpirationTime()
                                .toMillis()));
                return StringUtils.isEmpty(oss.getDomain()) ? url.toString() : oss.getDomain() + url.getPath() + "?" + url.getQuery();
            } else {
                return oss.getDomain() + path;
            }
        }

        return path;
    }
}
